﻿#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx
from core.event.eventdispatcher import EventDispatcher
from core.event.mouseevent import MouseEvent
from core.utils.singleton import singleton
from core.utils.commandmanager import CommandManager

class MenuObject(EventDispatcher,object):
    
    TYPE_SEPARATOR=wx.ITEM_SEPARATOR
    TYPE_CHECK=wx.ITEM_CHECK
    TYPE_MENU=-100
    TYPE_NORMAL=wx.ITEM_NORMAL
    
    def __init__(self,mainframe,name,parent=None,wxObject=None,type=wx.ITEM_NORMAL):
        self.childs={}
        self._cmd=None
        self.childs_index=[]
        self.parent=parent
        self.wxObject=wxObject
        self.type=type
        self.name=name
        self.index=-1
        self.id=wx.NewId()
        self.currentIndex=0
        self.help=""
        self._checked=False
        self.hasChild=False
        self.args=[]
        mainframe.Bind(wx.EVT_MENU, self._onClick, id=self.id)


    def setCommand(self,cmd,*args):
        self._cmd=cmd
        self.args=args

    def addChild(self,menuObject,index=-1):
        self.childs[menuObject.name]=menuObject
        menuObject.index=index;
        
        if menuObject.index<0:
            menuObject.index=len(self.childs_index)-menuObject.index+1
        self.childs_index.insert(menuObject.index,menuObject)
    
    def check(self,checked):
        self._checked=checked
        if self.wxObject:
            self.wxObject.Check(checked)
        elif self.getParent().wxObject and len(self.childs):
            self.getParent().wxObject.Check(self.id,checked)
    def isCheck(self):
        return self._checked
    
    def _append(self,menuObject):
        if (len(menuObject.childs) and menuObject.type != wx.ITEM_SEPARATOR) or not self.parent:
            self.type=MenuObject.TYPE_MENU
            menuObject.wxObject=wx.Menu()
        if not self.parent:
            self.wxObject.Append(menuObject.wxObject,menuObject.name)
        elif self.type == wx.ITEM_SEPARATOR:
            self.getParent()._append(menuObject)
        elif menuObject.wxObject and isinstance(menuObject.wxObject,wx.Menu):
            self.type=MenuObject.TYPE_MENU
            self.wxObject.AppendMenu(menuObject.id,menuObject.name,menuObject.wxObject)
        else:
            menuObject.wxObject=self.wxObject.Append(menuObject.id,menuObject.name,menuObject.help,menuObject.type)
            
    def build(self):
        cpt=0
        if self._checked:
            self.check(self._checked)

        for mObject in self.childs_index:
            if mObject.wxObject:
                try:
                    mObject.disable()
                except:
                    pass
                #mObject.wxObject.Destroy()
                mObject.wxObject=None
            cpt+=1
            self._append(mObject)
            self.index=cpt
            mObject.build()
        #self.wxObject.Destroy()
    
    def getParent(self):
        if self.parent.type== wx.ITEM_SEPARATOR:
            return getParent()
        else:
            return self.parent
        
    def getChildIndex(self,mObject):
        self.index=self.childs_index.index(mObject)
        return self.index

    def addEventListener(self, eventType, function, *arg):
        EventDispatcher.addEventListener(self, eventType, function, *arg)
        #if eventType==MouseEvent.MOUSE_CLICK:
        #    Core().getMainFrame().Bind(wx.EVT_MENU, self._onClick, id=self.id)
            
    def _onClick(self, e):
        if self._cmd:
            CommandManager().execute(self._cmd,*self.args)
        self.dispatchEvent(MouseEvent(MouseEvent.MOUSE_CLICK,e.GetId(),e))
    
    #def removeChild(self.mObject):
    #    self.
    
    
    def __repr__(self):
        return 'MenuObject:'+self.name

    def destroyChild(self,menuObject):
        self.wxObject.Remove(menuObject.id)
        menuObject.wxObject.Destroy()
        self.childs[menuObject.name]=None
    
    def destroy():
        self.getParent().destroyChild(self)
    
    def disable(self): #TODO a completer
        self.getParent().Remove(self.id)
        
    def clear(self):
        for child in self.childs:
            if(self.childs[child].wxObject):
                self.destroyChild(self.childs[child])
        self.childs={}
        self.childs_index=[]



class MainMenuObject(MenuObject):
    def __init__(self,mainframe,parent=None):
        MenuObject.__init__(self,mainframe,"main",parent,self)
        self.mainframe=mainframe
        
    def quickMenu(self,*menusNames):
        menuObject=self
        cpt=0
        id=None
        position=-1
        for name in menusNames:
            cpt+=1
            if menuObject.childs.has_key(name):
                menuObject=menuObject.childs[name]
            elif type(name)==int :
                position=name
            elif name[0]=="|":
                mobject=MenuObject(self.mainframe,name,menuObject,None,wx.ITEM_SEPARATOR)
                menuObject.addChild(mobject,position)
                position=-1
                menuObject=mobject
            elif name[0:2]=="[]":
                mobject=MenuObject(self.mainframe,name[2:],menuObject,None,wx.ITEM_CHECK)
                menuObject.addChild(mobject,position)
                position=-1
                menuObject=mobject
            elif name[0:3]=="[x]":
                mobject=MenuObject(self.mainframe,name[3:],menuObject,None,wx.ITEM_CHECK)
                menuObject.addChild(mobject,position)
                position=-1
                menuObject=mobject
                menuObject.check(True)
            else:
                mobject=MenuObject(self.mainframe,name,menuObject)
                menuObject.addChild(mobject,position)
                position=-1
                menuObject=mobject
            
        return menuObject
    
    
 
    
class Menu(wx.Menu,MainMenuObject):
    def __init__(self,mainframe):
        wx.Menu.__init__(self)
        MainMenuObject.__init__(self,mainframe,self)
        
    
    
    
@singleton
class MainMenu(wx.MenuBar, MainMenuObject):
    def __init__(self,mainframe):
        wx.MenuBar.__init__(self)
        MainMenuObject.__init__(self,mainframe)
        
    def build(self):
        for mObject in self.childs_index:
            if mObject.wxObject:
                self.Remove(0)
        MenuObject.build(self)
        
        